﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace IGG
{
    /// <summary>
    /// Main Output
    /// </summary>
    public static class Output
    {
        public enum OUTPUTS {TEXT, CONSOLE, HYBRID}

        public static OUTPUTS CURRENT_OUTPUT { get; set; }
        public static string TEXT_OUTPUT_PATH { get; set; }
        public static bool ERROR_MODE { get; set; }

        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        const int SW_HIDE = 0;
        const int SW_SHOW = 5;

        /// <summary>
        /// Initialize the output
        /// </summary>
        public static void Initialize()
        {
            Console.OutputEncoding = Encoding.GetEncoding(Constants.COMMANDLINE_ENCODING);
            if (CURRENT_OUTPUT == OUTPUTS.CONSOLE || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                Console.SetWindowSize(80, Constants.COMMANDLINE_HEIGHT);
            }
            else
            {
                //Console.SetWindowSize(80, 5);
                var handle = GetConsoleWindow();

                // Hide
               ShowWindow(handle, SW_HIDE);
            }
        }

        /// <summary>
        /// Format a long text for the console
        /// </summary>
        public static void FormatLongText(string longText)
        {
            int constantMax = 75;
            if (CURRENT_OUTPUT == OUTPUTS.TEXT)
            {
                constantMax = 170;
            }

            string[] words = longText.Split(new char[] { ' ' });
            for (int i = 0; i < words.Length; i++)
            {
                string sentence = words[i];
                bool continued = true;
                while (continued)
                {
                    if ((i + 1) < words.Length)
                    {
                        if ((sentence.Length + 1 + words[i + 1].Length) < constantMax)
                        {
                            sentence += " " + words[++i];
                        }
                        else
                        {
                            continued = false;
                        }
                    }
                    else
                    {
                        continued = false;
                    }
                }

                WriteLine(" " + sentence);
            }

        }

        public static void SetTopCursor()
        {
            if (CURRENT_OUTPUT == OUTPUTS.CONSOLE || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                Console.CursorTop = 0;
                Console.CursorLeft = 0;
            }
            else
            {
                
            }
        }

        public static void SetTitle(string title)
        {
            if (CURRENT_OUTPUT == OUTPUTS.CONSOLE || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                Console.Title = title;
            }
            else
            {
                Console.Title = "Debug";
            }
        }

        public static void Clear()
        {
            if (CURRENT_OUTPUT == OUTPUTS.CONSOLE || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                Console.Clear();
            }
            if (CURRENT_OUTPUT == OUTPUTS.TEXT || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                StreamWriter writer = null;
                try
                {
                    writer = new StreamWriter(TEXT_OUTPUT_PATH, false);
                    writer.Write("");
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(ex.StackTrace);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Close();
                        writer = null;
                    }
                }
            }
        }

        public static string WaitForInput()
        {
            if (CURRENT_OUTPUT == OUTPUTS.CONSOLE || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                Console.Read();
                return "";
            }
            else
            {
                return "";
            }
        }

        public static void WriteLine()
        {
            WriteLine("");
        }

        public static void Write(char car)
        {
            Write(car.ToString());
        }

        public static bool IsConsoleKeyAvailable()
        {
            return Console.KeyAvailable;
        }

        public static void Write(string line)
        {
            if (CURRENT_OUTPUT == OUTPUTS.TEXT || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                StreamWriter writer = null;
                try
                {
                    writer = new StreamWriter(TEXT_OUTPUT_PATH, true, Encoding.Unicode);
                    if (ERROR_MODE)
                    {
                        writer.Write(line.ToUpper());
                    }
                    else
                    {
                        writer.Write(line);
                    }

                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(ex.StackTrace);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Close();
                        writer = null;
                    }
                }
            }
            if (CURRENT_OUTPUT == OUTPUTS.CONSOLE || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                if (ERROR_MODE)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write(line);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                else
                {
                    Console.Write(line);
                }

            }
        }

        public static void WriteLine(string line)
        {
            if (CURRENT_OUTPUT == OUTPUTS.TEXT || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                StreamWriter writer = null;
                try
                {
                    writer = new StreamWriter(TEXT_OUTPUT_PATH, true, Encoding.Unicode);
                    if (ERROR_MODE)
                    {
                        writer.WriteLine(line.ToUpper());
                    }
                    else
                    {
                        writer.WriteLine(line);
                    }
                    
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(ex.StackTrace);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Close();
                        writer = null;
                    }
                }
            }
            if (CURRENT_OUTPUT == OUTPUTS.CONSOLE || CURRENT_OUTPUT == OUTPUTS.HYBRID)
            {
                if (ERROR_MODE)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(line);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                else
                {
                    Console.WriteLine(line);
                }
                
            }
        }
    }
}
